package com.anker.consistency.aspect;


import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import lombok.extern.log4j.Log4j2;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
import java.util.Objects;

@Log4j2
@Aspect
@Component
@Order(1)
public class MyDsAspectj {


    @Around("@annotation(ds)")
    public Object lock(ProceedingJoinPoint point, MyDs ds){

        String[] parameterNames = ((MethodSignature) point.getSignature()).getParameterNames();
        Object[] args = point.getArgs();
        ExpressionParser parser = new SpelExpressionParser();
        Expression expression = parser.parseExpression(ds.expression());
        StandardEvaluationContext ctx = new StandardEvaluationContext();
        for (int i = 0; i < parameterNames.length; i++) {
            ctx.setVariable(parameterNames[i], args[i]);
        }
        String sourceName = Objects.requireNonNull(expression.getValue(ctx)).toString();
        try {
            DynamicDataSourceContextHolder.push(sourceName);
            return point.proceed();
        } catch (Throwable e) {
            log.error(e.getMessage(),e);
        } finally {
            DynamicDataSourceContextHolder.clear();
        }
        return null;
    }
}
